/**
 * @addtogroup mfc_string
 * mfc_string
 * @{
 */
/**
 * @file         mfc_string.h
 * @brief        字符串对象相关,TMfString的self对象内部不判断是否为空
 * @note         多线程不安全，可重入
 * @author       尤胜坤[Akee](ysk@hopechart.com)
 * @date         2020-3-7
 * @version      1.4
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2019-9-10   <td>1.0                   <td>Akee            <td>创建初始版本
 * <tr><td>2019-12-20  <td>1.1                   <td>Akee            <td>增加MfStringFillChar和TMfStringDumpStringCatCharWithLen接口
 * <tr><td>2020-02-15  <td>1.2                   <td>Akee            <td>增加MfValInt/MfValIntWithLen/MfValInt64/MfValInt64WithLen/ \
 MfStrToInt/MfStrToInt64/MfStrToIntDef/MfStrToInt64Def/MfIntToAscii/MfInt64ToAscii/MfIntToStr/ \
 MfInt64ToStr/TMfStringToInt/TMfStringToInt64/TMfStringToIntDef/TMfStringToInt64Def接口,按照叶工评审修改
 * <tr><td>2020-2-21   <td>1.3                   <td>Akee            <td>MfValInt64/MfValInt64WithLen接口调用LowerChar空函数问题
 * <tr><td>2020-3-7    <td>1.4                   <td>Akee            <td>CreateString和CreateStringWithLen加入Mf的域前缀,MfStringLengthCopy改为Int32返回值

 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _MFC_STRING_H_
#define _MFC_STRING_H_

#include "ofc_types.h"
#include "ofc_object.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 字符串转换为Int32类型变量
 * @param str: 需要转换的字符串
 * @param code_ret: 转换的结果,若为0表示成功,否则表示错误的位置
 * @return 
 * @par 代码示例
 * @code
    例如: "123.3"        -> result = 123, ACode = 4
          "123456"       -> result = 123456, ACode = 0
          "12345678901"  -> result = 1234567890, ACode = 11
 * @endcode
 */
Int32 MfValInt(const char *str, Int32 *code_ret);
Int32 MfValIntWithLen(const char *str, Int32 length, Int32 *code_ret);

/**
 * 字符串转换为Int64类型变量
 * @param str: 需要转换的字符串
 * @param code_ret: 转换的结果,0: 成功; 其他: 错误的位置
 * @return 
 * @par 代码示例
 * @code
    例如: "123.3"             -> result = 123, ACode = 4
          "12345678907897497" -> result = 12345678907897497, ACode = 0
 * @endcode
 */
Int64 MfValInt64(const char *str, Int32 *code_ret);
Int64 MfValInt64WithLen(const char *str, Int32 length, Int32 *code_ret);

/**
 * 字符串转换为Int32
 * @param str: 需要转换的字符串
 * @return 转换后的值
 * @note 转换失败则返回0
 */
Int32 MfStrToInt(const char *str);

/**
 * 字符串转换为Int64
 * @param str: 需要转换的字符串
 * @return 转换后的值
 * @note 转换失败则返回0
 */
Int64 MfStrToInt64(const char *str);

/**
 * 字符串转换为Int32
 * @param str: 需要转换的字符串
 * @return 转换后的值
 * @note 转换失败则返回defalut_value
 */
Int32 MfStrToIntDef(const char *str, Int32 defalut_value);

/**
 * 字符串转换为Int64
 * @param str: 需要转换的字符串
 * @return 转换后的值
 * @note 转换失败则返回defalut_value
 */
Int64 MfStrToInt64Def(const char *str, Int64 defalut_value);

/**
 * Int32值转换为ascii码
 * @param value: 需要转换的数值
 * @param buf: 转换后存放的ascii码的地址,例如十进制需要有至少10个字节的大小,内部不判断参数的有效性
 * @param base: 转换的进制
 * @return 转换后字符串的长度
 * @note 不同的进制下需要注意buf的长度
 */
Int32 MfIntToAscii(Int32 value, char *buf, Int32 base);

/**
 * Int64值转换为ascii码
 * @param value: 需要转换的数值
 * @param buf: 转换后存放的ascii码的地址,内部不判断参数的有效性
 * @param base: 转换的进制
 * @return 转换后字符串的长度
 * @note 不同的进制下需要注意buf的长度
 */
Int32 MfInt64ToAscii(Int64 value, char *buf, Int32 base);

/**
 * 从src拷贝最大dst_size - 1长度的字符串,如果str的字符串长度大于dst_size，则拷贝str_len - 1
 * @param dst: 拷贝的目的地址
 * @param src: 拷贝的来源字符串
 * @param dst_size: 拷贝的目的地址大小
 * @return 实际拷贝的字节
 */
Int32 MfStringLengthCopy(char *dst, const char *src, Int32 dst_size);

/**
 * 从str取字符串往buf填字符串,超出部分截断,不足部分填0
 * @param str: 填充的字符串,当NULL时,buf中全部填充为0
 * @param buf: 需要填充的缓存
 * @param buf_size: 缓存大小
 * @return 
 */
void MfStringFillChar(const char *str, char *buf, Int32 buf_size);

/**
 * 当为'A' ~ 'Z'时转为小写
 * @param c: 字符
 * @return 小写字符
 */
char MfStringLowerCase(char c);

/**
 * 当为'a' ~ 'z'时转为大写
 * @param c: 字符
 * @return 大写字符
 */
char MfStringUpperCase(char c);

/**
 * 当为'a' ~ 'z'或者'A' ~ 'Z'时,大小写反转
 * @param c: 字符
 * @return 翻转后的字符
 */
char MfStringInverseCase(char c);

/**
 * 字符串结构体类
 */
typedef struct TMfStringTag TMfString;
struct TMfStringTag 
{
    TOfObject parent_;              ///< 父亲对象

PROTECTED
    TOfVirtualMethod Destroy_;      ///< 析构方法

    char *string_;                  ///< 字符串内容
    Int32 length_;                  ///< 字符长度 
PRIVATE

};

/**
 * Int32类型转换为字符串创建TMfString对象
 * @param value: 需要转换的数值
 * @return 字符串对象,注意需要释放
 * @note 返回值需要通过OfDestroyObject来释放
 */
TMfString *MfIntToStr(Int32 value);

/**
 * Int64类型转换为字符串创建TMfString对象
 * @param value: 需要转换的数值
 * @return 字符串对象,注意需要释放
 * @note 返回值需要通过OfDestroyObject来释放
 */
TMfString *MfInt64ToStr(Int64 value);

/**
 * 构造函数,通过str和length，构造出TMfString的实例
 * @param self: 对象指针
 * @param str: 字符串内容
 * @param length: 字符串长度
 * @return True: 成功; False: 失败
 */
Bool TMfStringCreate(TMfString *self, const char *str, Int32 length);

/**
 * 创建一个TMfString的对象,内部会涉及内存分配，需要手动判断结果
 * @param str: 字符串内容,可为NULL
 * @return 失败: NULL; 成功: TMfString的对象实体
 */
TMfString *MfCreateString(const char *str);

/**
 * 创建一个TMfString的对象
 * @param str: 字符串内容,,可为NULL
 * @param length: 需要创建的字符串长度,可<= 0
 * @return 失败: NULL; 成功: TMfString的对象实体
 */
TMfString *MfCreateStringWithLen(const char *str, Int32 length);

/**
 * 从self对象实体中拷贝从index开始位置长度为length的字符串生成TMfString对象,内部会调用TMfStringCreate
 * @par 代码示例
 * @code
   TMfString name;
   
   if (TMfStringCreate(&name, "Alise", strlen("Alise")))
   {
        TMfString *dump_name = TMfStringCopyString(&name, 0, TMfStringLength(&name));

        if (dump_name != NULL)
        {
            ...

            FreeRfObject((TOfObject *)dump_name);
        }
   }

    FreeRfObject((TOfObject *)&name);
 * @endcode
 * @param self: 对象指针
 * @param index: 拷贝开始的位置，若<0,则从0开始拷贝
 * @param length: 需要拷贝的长度
 * @return 失败: NULL; 成功: TMfString的对象实体
 */
TMfString *TMfStringCopyString(TMfString *self, Int32 index, Int32 length);

/**
 * 从self拷贝一份TMfString的实体，内部会调用TMfStringCreate
    TMfString name;

    if (TMfStringCreate(&name, "Alise", strlen("Alise")))
    {
        TMfString *dump_name = TMfStringDumpString(&name);

        if (dump_name != NULL)
        {
            ...

            FreeRfObject((TOfObject *)dump_name);
        }
    }

    FreeRfObject((TOfObject *)&name);
 * @param self: 对象指针
 * @return 失败: NULL; 成功: TMfString的对象实体
 */
TMfString *TMfStringDumpString(TMfString *self);

/**
 * 复制一份TMfString src到self对象,会先释放self对象的字符串内容，再分配内存进行拷贝
 * @param self: 对象指针
 * @param src: 需要从此对象中赋值
 * @return True: 成功; False: 失败
 */
Bool TMfStringAssignString(TMfString *self, TMfString *src);

/**
 * 复制一份字符串到self对象,会先释放self对象的字符串内容，再分配内存进行拷贝
 * @param self: 对象指针
 * @param str: 需要复制的字符串
 * @return True: 成功; False: 失败
 */
Bool TMfStringAssignChar(TMfString *self, const char *str);

/**
 * 复制一份字符串到self对象,会先释放self对象的字符串内容，再分配内存进行拷贝
 * @param self: 对象指针
 * @param src: 需要复制的字符
 * @param length: 字符的长度
 * @return True: 成功; False: 失败
 */
Bool TMfStringAssignCharWithLen(TMfString *self, const char *src, Int32 length);

/**
 * 追加字符串,将str中的字符串追加到self对象的末尾
 * @param self: 对象指针
 * @param str: 追加的字符串实体
 * @note 若str为空，则返回追加失败，str中的字符串为空，追加还是成功
 * @return True: 成功; False: 失败
 */
Bool TMfStringCatString(TMfString *self, TMfString *str);

/**
 * 追加字符串,将str字符串追加到self对象的末尾
 * @param self: 对象指针
 * @param str: 追加的字符串
 * @return True: 成功; False: 失败
 */
Bool TMfStringCatChar(TMfString *self, const char *str);

/**
 * 追加字符串,将str字符串追加到self对象的末尾
 * @param self: 对象指针
 * @param str: 追加的字符串
 * @param length: 追加的长度
 * @return True: 成功; False: 失败
 */
Bool TMfStringCatCharWithLen(TMfString *self, const char *str, Int32 length);

/**
 * 先拷贝self对象生成新对象，再追加str字符串,将str字符串追加到self对象的末尾形成新的结果返回
 * @param self: 对象指针
 * @param str: 追加的字符串
 * @param length: 追加的长度
 * @return 新生成的对象指针
 * @note 不会对self对象做修改
 */
TMfString *TMfStringDumpStringCatCharWithLen(TMfString *self, const char *str, Int32 length);

/**
 * 查找子字符串位置
 * @param self: 对象指针
 * @param sub_str: 查找的子字符串对象
 * @return -1: 查询不到; >=0: 查找到的位置
 */
Int32 TMfStringPosString(TMfString *self, TMfString *sub_str);

/**
 * 查找子字符串位置
 * @param self: 对象指针
 * @param sub_str: 查找的子字符串
 * @param sub_str_size: 子字符串大小
 * @return -1: 查询不到; >=0: 查找到的位置
 */
Int32 TMfStringPosChar(TMfString *self, const char *sub_str, Int32 sub_str_size);

/**
 * 文本比较(不区分大小写)
 * @param self: 对象指针
 * @param str: 比较的字符串类
 * @param case_sensitive: 是否区分大小写
 * @return self < str返回负数, self == str返回0, 否则返回正数
 */
Int32 TMfStringCompareStringText(TMfString *self, TMfString *str, Bool case_sensitive);

/**
 * 文本比较(不区分大小写)
 * @param self: 对象指针
 * @param str: 比较字符串
 * @param case_sensitive: 是否区分大小写
 * @return self < str返回负数, self == str返回0, 否则返回正数
 */
Int32 TMfStringCompareCharText(TMfString *self, const char *str, Bool case_sensitive);

/**
 * 是否相同文本(不区分大小写)
 * @param self: 对象指针
 * @param str: 比较的字符串类
 * @param case_sensitive: 是否区分大小写
 * @return True: 相等; False: 不相等
 */
Bool TMfStringSameStringText(TMfString *self, TMfString *str, Bool case_sensitive);

/**
 * 是否相同文本(不区分大小写)
 * @param self: 对象指针
 * @param str: 比较的字符串类
 * @param case_sensitive: 是否区分大小写
 * @return True: 相等; False: 不相等
 */
Bool TMfStringSameCharText(TMfString *self, const char *str, Bool case_sensitive);

/**
 * 设置字符串的长度.如果length比原先字符串的长度小,则保留原先的length个字符.如果大,则在原先的字符串后面追加随机字符
 * @param self: 对象指针
 * @param length: 需要设置的字符串长度
 * @return True: 成功; False: 失败
 */
Bool TMfStringSetLength(TMfString *self, Int32 length);

/**
 * 把字符串的所有字符改成小写
 * @param self: 对象指针
 * @return 
 */
void TMfStringToLowerCase(TMfString *self);

/**
 * 把字符串的所有字符改成大写
 * @param self: 对象指针
 * @return 
 */
void TMfStringToUpperCase(TMfString *self);

/**
 * 格式化生成字符串内容
 * @param buf: 格式化存放的内存地址
 * @param size: 内存大小
 * @param fmt: 不定参数
 * @return 生成的字符串对象
 */
TMfString *StringFormatWithLen(char *buf, Int32 size, char *fmt, ...);

/**
 * 格式化字符串内容，内部会释放self中的字符串再重新分配
 * @param self: 对象指针
 * @param buf: 格式化过程中产生的临时内存
 * @param size: 内存大小
 * @param fmt: 不定参数
 * @return 
 */
Bool FormatStringWithLen(TMfString *self, char *buf, Int32 size, char *fmt, ...);

/**
 * 把字符串的所有字符大小写反转
 * @param self: 对象指针
 * @return 
 */
void TMfStringToInverseCase(TMfString *self);

/**
 * 从TMfString对象中拷贝字符串到dst内存
 * @param self: 对象指针
 * @param dst: 拷贝的去向内存地址
 * @param dst_size: 去向内存地址的大小
 * @return 实际拷贝的大小
 */
Int32 TMfStringCopyToChar(TMfString *self, char *dst, Int32 dst_size);

/**
 * 获取TMfString字符串对象中从start_pos位置开始第一次出现c的位置
 * @param self: 对象指针
 * @param c: 查找的字符
 * @param start_pos: 开始查找的位置,需要>=0
 * @return -1: 查找失败; 其他: 查找的具体位置,从0开始
 */
Int32 TMfStringIndexOfChar(TMfString *self, char c, Int32 start_pos);

/**
 * 设置当前字符串为str的前面length个字符 
 * @param self: 对象指针
 * @param str: 源字符串
 * @param length: 需要从str中复制的字符长度
 * @return True: 成功; False: 失败
 */
Bool TMfStringSetString(TMfString *self, const char *str, Int32 length);

/*
 * 获取字符串中的字符内容
 * @param self: 对象指针
 * @return 字符内容
 */
const char *TMfStringString(TMfString *self);

/*
 * 获取字符串中的长度
 * @param self: 对象指针
 * @return 字符长度
 */
Int32 TMfStringLength(TMfString *self);

/*
 * 字符串转换为Int32数值
 * @param self: 对象指针
 * @return 转换后的数值
 * @note 转换失败则返回0
 */
Int32 TMfStringToInt(TMfString *self);

/*
 * 字符串转换为Int64数值
 * @param self: 对象指针
 * @return 转换后的数值
 * @note 转换失败则返回0
 */
Int64 TMfStringToInt64(TMfString *self);

/*
 * 字符串转换为Int32数值
 * @param self: 对象指针
 * @return 转换后的数值
 * @note 转换失败则返回default_value
 */
Int32 TMfStringToIntDef(TMfString *self, Int32 default_value);

/*
 * 字符串转换为Int64数值
 * @param self: 对象指针
 * @return 转换后的数值
 * @note 转换失败则返回default_value
 */
Int64 TMfStringToInt64Def(TMfString *self, Int64 default_value);


#ifdef __cplusplus
}
#endif

#endif// _MFC_STRING_H_
/**
 * @}
 */

